package vip.aster.websocket.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.socket.*;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;
import vip.aster.framework.security.entity.UserDetail;
import vip.aster.websocket.constant.WebSocketConstants;
import vip.aster.websocket.utils.WebSocketUtils;
import vip.aster.websocket.vo.WebSocketMessageVO;

import java.util.List;
import java.util.Map;

/**
 * WebSocketHandler
 *
 * @author Aster
 * @since 2024/3/11 16:36
 */
@Slf4j
public class AsterWebSocketHandler extends AbstractWebSocketHandler {
    /**
     * 连接成功后
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        UserDetail loginUser = (UserDetail) session.getAttributes().get(WebSocketConstants.LOGIN_USER_KEY);
        WebSocketUsers.addSession(loginUser.getId(), session);
        log.info("[connect] sessionId: {},userId:{},username:{}", session.getId(), loginUser.getId(), loginUser.getUsername());
    }

    /**
     * 处理发送来的文本消息
     *
     * @param session 会话
     * @param message 消息
     * @throws Exception 异常
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        Map<String, Object> attributes = session.getAttributes();
        UserDetail loginUser = (UserDetail) attributes.get(WebSocketConstants.LOGIN_USER_KEY);
        List<String> userIds = List.of(loginUser.getId());
        WebSocketMessageVO messageVO = new WebSocketMessageVO();
        messageVO.setSessionKeys(userIds);
        String payload = message.getPayload();
        messageVO.setMessage(payload);
        WebSocketUtils.publishMessage(messageVO);
    }

    @Override
    protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {
        super.handleBinaryMessage(session, message);
    }

    /**
     * 心跳监测的回复
     *
     * @param session 会话
     * @param message 消息
     * @throws Exception 异常
     */
    @Override
    protected void handlePongMessage(WebSocketSession session, PongMessage message) throws Exception {
        WebSocketUtils.sendPongMessage(session);
    }

    /**
     * 连接出错时
     *
     * @param session   会话
     * @param exception 异常
     * @throws Exception 异常
     */
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        log.error("[transport error] sessionId: {} , exception:{}", session.getId(), exception.getMessage());
    }

    /**
     * 连接关闭后
     *
     * @param session 会话
     * @param status  关闭状态
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
        UserDetail loginUser = (UserDetail) session.getAttributes().get(WebSocketConstants.LOGIN_USER_KEY);
        WebSocketUsers.removeSession(loginUser.getId());
        log.info("[disconnect] sessionId: {},userId:{},username:{}", session.getId(), loginUser.getId(), loginUser.getUsername());
    }

    /**
     * 是否支持分片消息
     *
     * @return true/false
     */
    @Override
    public boolean supportsPartialMessages() {
        return false;
    }
}
